﻿// See https://aka.ms/new-console-template for more information
using FlyweightPattern;

/*Console.WriteLine("Hello, World!");

FlyweightPattern：享元模式

// 准备打印 Eleven
BaseWord e = new E();
BaseWord l = new L();
//BaseWord e2 = new E();
BaseWord v = new V();
//BaseWord e3 = new E();
BaseWord n = new N();

// 重用了 e 对象，提升了性能。但是在其他方法，其他类、甚至其他类库、其他线程都需要重用对象来提升性能怎么办？
Console.WriteLine($"{e.Get()}{l.Get()}{e.Get()}{v.Get()}{e.Get()}{n.Get()}");

OtherClass otherClass = new OtherClass();
// 说到对象服用最容易想到的是单例
// 那么单例就可以对像的复用了，性能优化了，
// 但是要做到单例，需要改造类，破坏类的封装
S s1 = S.GetInstance();
S s2 = S.GetInstance();
S s3 = S.GetInstance();
Console.WriteLine($"{object.ReferenceEquals(s1,s2)}");
Console.WriteLine($"{object.ReferenceEquals(s2,s3)}");*/

// 又想对象重用，又不想破坏类的封装怎么办？
// 1 统一对象入口，然后在统一入口中想办法重用对象
List<Task> tasks = new List<Task>();
for (int i = 0; i < 5; i++)
{
    tasks.Add(Task.Run(() =>
    {
        BaseWord e = FlyweightFactory.CreateWord(WordType.E);
        BaseWord l = FlyweightFactory.CreateWord(WordType.L);
        BaseWord v = FlyweightFactory.CreateWord(WordType.V);
        BaseWord n = FlyweightFactory.CreateWord(WordType.N);
        Console.WriteLine($"{e.Get()}{l.Get()}{e.Get()}{v.Get()}{e.Get()}{n.Get()}");
    }));
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine("**************************************************");
/*Parallel.For(0, 5, i =>
{
    BaseWord e = FlyweightFactory.CreateWord(WordType.E);
    BaseWord l = FlyweightFactory.CreateWord(WordType.L);
    BaseWord v = FlyweightFactory.CreateWord(WordType.V);
    BaseWord n = FlyweightFactory.CreateWord(WordType.N);
    Console.WriteLine($"{e.Get()}{l.Get()}{e.Get()}{v.Get()}{e.Get()}{n.Get()}");
});*/

//OtherClass otherClass = new OtherClass();

/*// 享元模式：为了解决对象的复用问题，提供第三方的管理，能完成对象的复用
// 1 享元模式不像单例，不会强制保证单个对象
// 2 享元工厂也可以初始化多个对象 --- 其他地方需要使用对象可以找它那（修改状态）用完之后在放回去，主要解决非托管资源 --- 池化资源管理
//BaseWord e = FlyweightFactory.CreateWord(WordType.E);
//BaseWord e1 = FlyweightFactory.CreateWord(WordType.E);
//E e2 = new E();
//E e3 = new E();
//Console.WriteLine(object.ReferenceEquals(e,e2));
//Console.WriteLine(object.ReferenceEquals(e, e3));
//Console.WriteLine(object.ReferenceEquals(e,e1));*/

/*string teacher1 = "Eleven";
string teacher2 = "Eleven";
OtherClass otherClass = new OtherClass();
Console.WriteLine(object.ReferenceEquals(teacher1,teacher2));
Console.WriteLine(object.ReferenceEquals(teacher1,otherClass.Teacher));

Console.WriteLine("**********************************");
string teacher3 = string.Format("Ele{0}", "ven");
string teacher4 = "Ele" + "ven";
Console.WriteLine(object.ReferenceEquals(teacher1, teacher3));
Console.WriteLine(object.ReferenceEquals(teacher3, otherClass.Teacher));
Console.WriteLine(object.ReferenceEquals(teacher1, teacher4));
Console.WriteLine(object.ReferenceEquals(teacher3, otherClass.teacher2));

string firstPart = "Ele";
string teacher5 = firstPart + "ven";
*/
